package com.apanal.qlife.common.jcaptcha;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.apanal.qlife.common.annotation.LogType;
import com.apanal.qlife.common.aop.SysLogAspect;
import com.apanal.qlife.common.constants.Constants;
import com.apanal.qlife.sys.model.SysLog;

/**
 * 自定义身份认证/登录过滤器
 * 
 * 
 * @author shuliangxing
 * 
 * @date 2015-9-10下午5:42:42
 */
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

	private static final Logger log = Logger
			.getLogger(MyFormAuthenticationFilter.class);

	@Autowired
	private SysLogAspect sysLogAspect;

	@Override
	protected boolean onAccessDenied(ServletRequest request,
			ServletResponse response, Object mappedValue) throws Exception {
		HttpServletRequest req = WebUtils.toHttp(request);
		HttpServletResponse rsp = WebUtils.toHttp(response);

		// 是否是ajax请求
		boolean isAjaxRequest = com.apanal.qlife.common.util.WebUtils
				.isAjaxRequest(req);
		// 当验证码验证失败时不再走身份认证拦截器
		if (request.getAttribute(getFailureKeyAttribute()) != null) {
			return true;
		}

		// 登录地址请求
		if (isLoginRequest(request, response)) {
			// post 提交登录
			if (isLoginSubmission(request, response)) {
				log.debug("Login submission detected.  Attempting to execute login.");
				return executeLogin(request, response);
			}
			// get 请求登录页面
			else {
				log.debug("Login page view.");
				// allow them to see the login page ;)

				// ajax请求返回未授权401状态码
				if (isAjaxRequest) {
					rsp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
					com.apanal.qlife.common.util.WebUtils.sendData(
							Constants.DEFAULT_MSG_AJAX_TIMEOUT, rsp);
					return false;
				}
				return true;
			}
		}
		// 非登录地址请求
		else {
			log.debug("Attempting to access a path which requires authentication.  Forwarding to the "
					+ "Authentication url [" + getLoginUrl() + "]");

			// saveRequestAndRedirectToLogin(request, response);

			// ajax请求返回未授权401状态码
			if (isAjaxRequest) {
				rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
				com.apanal.qlife.common.util.WebUtils.sendData(
						Constants.DEFAULT_MSG_AJAX_TIMEOUT, rsp);
			} else {
				// 不保存登录前的路径,统一跳转到首页
				redirectToLogin(request, response);
			}
			return false;
		}

	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token,
			Subject subject, ServletRequest request, ServletResponse response)
			throws Exception {
		HttpServletRequest req = WebUtils.toHttp(request);
		// 日志对象
		SysLog log = new SysLog();
		sysLogAspect.beforeLog(log, req);

		// 预留代码,目前登录统一采用最顶层页面登录,iframe子页面登录如果登录账号不一致会导致父页面登录人信息不一致
		// 解决ifram情况下当用户被踢时,用户请求时loginout、清空session,清空后会默认跳转到首页而导致ifram嵌套问题
		// 登录后根据backUrl参数跳转到之前请求的路径
		// 参考com.apanal.qlife.common.filter.ForceLogoutFilter
		// if (request.getParameter("backUrl") != null) {
		// super.setSuccessUrl(request.getParameter("backUrl"));
		// } else {
		// super.setSuccessUrl(AuthenticationFilter.DEFAULT_SUCCESS_URL);
		// }

		// 直接移除登录前的路径,统一跳转到首页
		WebUtils.getAndClearSavedRequest(request);
		boolean result = super
				.onLoginSuccess(token, subject, request, response);

		// 方法名
		String methodName = "com.apanal.qlife.common.jcaptcha.MyFormAuthenticationFilter.onLoginSuccess()";
		sysLogAspect.afterLog(log, req, methodName, "后台用户管理", "用户登录",
				LogType.LOGIN);

		return result;
	}

}
